.TITLE TTSUB .IDENT /08.01/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; ; 02-FEB-78 PETER WANNHEDEN ; ; PREVIOUSLY MODIFIED BY: ; ; P. WANNHEDEN ; D. R. DONCHIN ; T. LEKAS ; R. PHILPOTT ; S. ADAMS ; L. KOGAN ; ; ; MODIFIED FOR RSX-11M-PLUS V4.3 BY: ; ; M. W. ZAHAREE 28-JUN-89 08.00 ; MWZ009 -- DON'T CLOBBER OTHER BITS WHEN INITIALIZING U.AFLG FOR ACD ; ACD CALLS. ; ; L. KOGAN 5-OCT-89 08.01 ; LK750 -- CLEAR THE NUMBER OF BYTES IN CURRENT OUTPUT BUFFER ; (U.TOC) ; ; .MCALL PKTDF$,EVNDF$ PKTDF$ EVNDF$ .PSECT MAP6 ; ;+ ; TTSUBR - MISCELLANEOUS SUBROUTINES FOR TERMINAL DRIVER. ;- ; ; .SBTTL ALUCBX - ALLOCATE A UCB EXTENSION BLOCK ; ;+ ; ALUCBX - ALLOCATE A UCB EXTENSION (UCBX). ; ; INPUT: ; R5 POINTER TO U.TSTA ; ; OUTPUT: ; IF SUCCESS, OR IF UCBX ALREADY EXISTS: ; CC-C 0 ; R4 POINTER TO UCBX ; U.TUX POINTS TO UCBX ; UCBX INITIALIZED (ONLY IF UCBX WAS ALLOCATED) ; ; IF FAILURE: ; CC-C 1 ; ; REGISTERS ALTERED: R0,R2,R4 ;- ; .IF NDF T$$SPL ; .ENABL LSB ; ASSUME U.TUX,U.TSTA-2 ALUCBX::MOV -(R5),R4 ;IS THERE ALREADY A UCBX? CLC ;ASSUME YES BNE 10$ ;Y - EXIT WITH CC-C = 0 CALL ALTB ;N - ALLOCATE A BUFFER BCS 10$ ;FAILED - EXIT WITH CC-C = 1 MOV R2,R4 ;SAVE POINTER ; ; INITIALIZE A FEW CELLS ; ASSUME U.TCI,0 ;U.TCI ALREADY CLEARED BY ALTB CLR U.TCO(R2) ;NO CURRENT OUTPUT REQUEST CLR U.TOC(R2) ;NO REMAINING BYTES IN CURRENT OUTPUT BUFFER CLRB U.TISV(R2) ;INITIALIZE STATE VARIABLE ASSUME U.TITI&1,0 ASSUME U.TOTI,U.TITI+1 CLR U.TITI(R2) ;CLEAR INPUT AND OUTPUT TIMERS CLR U.TFPB(R2) ;CLEAR PROMPT BUF ADDRS/UNSOLICITED INPUT FLAG CLR U.TRTT(R2) ;ASSUME NOT A RTT FUNCTION .IF DF T$$EIO CLR U.TDIF(R2) ;CLEAR FIRST DEFAULT INPUT BUFFER POINTER .ENDC ;T$$EIO .IF DF T$$CCA!T$$SCA!T$$MHU!T$$ICS!T$$OOB ADD #U.TAST,R2 ;POINT TO UNSOLICITED INPUT ACB ADDRESS X = U.TAST ;SYMBOL NEEDED FOR ASSUME MACROS .IF DF T$$CCA CLR (R2)+ ;CLEAR ACB POINTER FOR UNSOLICITED INPUT X = X + 2 .ENDC ;T$$CCA .IF DF T$$SCA ASSUME U.TSCA,X X = X + 2 CLR (R2)+ ;CLEAR SWITCH CHARACTER ACB POINTER .ENDC ;T$$SCA .IF DF T$$MHU ASSUME U.TMHA,X X = X + 2 CLR (R2)+ ;CLEAR MODEM HANGUP ACB POINTER .ENDC ;T$$MHU .IF DF T$$ICS ASSUME U.TICA,X X = X + 2 CLR (R2)+ ;CLEAR ICS ACB/TEP POINTER .ENDC ;T$$ICS .IF DF T$$OOB ASSUME U.TOBA,X X = X + 2 CLR (R2) ;CLEAR OOB ACB/TEP POINTER .ENDC ;T$$OOB .ENDC ;T$$CCA!T$$SCA!T$$MHU!T$$ICS!T$$OOB MOV R4,(R5) ;SET UCBX POINTER ;EXIT WITH CC-C = 0 10$: MOV (R5)+,R4 ;RESTORE R5 AND GET UCBX IN R4 ;(OR 0 IF COMING FROM DEUCBX) 20$: RETURN ;RETURN ; ; .SBTTL DEUCBX - DEALLOCATE A UCB EXTENSION BLOCK ; ;+ ; DEUCBX - DEALLOCATE UCBX IF POSSIBLE. ; ; INPUT: ; R5 POINTER TO U.TSTA ; ; OUTPUT: ; IF LINE IS IDLE (BOTH INPUT AND OUTPUT), NOT ATTACHED ; AND THERE ARE NO FORK REQUESTS PENDING, ; THE UCBX (IF THERE IS ONE) IS DEALLOCATED. ; ; REGISTERS ALTERED: R0,R2,R4 ;- ; ; DEUCBX::MOV @R5,-(SP) ;GET STATUS WORD 1 BIC #^C,@SP ;CLEAR ALL BUT INPUT AND ;OUTPUT BUSY FLAGS BIS U.TFRQ-U.TSTA(R5),@SP ;OR WITH FORK REQUEST FLAGS BIS U.ATT-U.TSTA(R5),(SP)+ ;OR WITH ATTACH POINTER BNE 20$ ;IF NE DON'T DEALLOCATE .IF DF T$$IDO TST $MCRPT ;IS THE MCR DISPATCHER INSTALLED? BEQ 20$ ;IF EQ NO - DON'T DEALLOCATE THE UCBX .ENDC ;T$$IDO MOV -(R5),R2 ;GET UCBX BEQ 10$ ;NONE - EXIT CLR (R5)+ ;OK - CLEAR POINTER ;FALL THRU TO "DETB" ; .DSABL LSB .IFTF ;NDF T$$SPL ; .SBTTL DEALLOCATE A TERMINAL BUFFER ; ;+ ; DETB - DEALLOCATE TERMINAL BUFFER. ; ; INPUT: ; R2 BUFFER ADDRESS ; ; OUTPUT: ; BUFFER DEALLOCATED TO TT-DRIVER POOL OR SYSTEM POOL. ; ; REGISTERS ALTERED: R0,R2 ;- ; ; DETB:: CMP R2,#120000 ;IN TT-DRIVER POOL? BLO 10$ ;N - JUMP MOV FREEB,@R2 ;Y - ADD TO FRONT OF FREE BUFFER LIST MOV R2,FREEB RETURN 10$: MOV R1,-(SP) ;SAVE R1,R3 MOV R3,-(SP) MOV R2,R0 ;GET BUFFER ADDRESS MOV #T$$BFL,R1 ;GET LENGTH CALL $DEACB ;DEALLOCATE TO SYSTEM POOL MOV (SP)+,R3 ;RESTORE REG'S MOV (SP)+,R1 RETURN .PSECT MAP5 .IF DF T$$CCA!T$$SCA!T$$MHU!T$$ICS!T$$OOB .PAGE .SBTTL . DQACB - AST CONTROL BLOCK WAS DEQUEUED BY SYSXT ; ;+ ; **-DQACB - AST CONTROL BLOCK DEQUEUE PROCESSING ; ; THIS SUBROUTINE IS CALLED WHEN SYSXT DEQUEUES AN AST CONTROL BLOCK ; THAT HAS A.CBL=0 AND THE DOUBLEWORD ADDRESS OF THIS ROUTINE IN A.KSR5 AND ; A.DQSR. IF THIS ACB GOT MARKED FOR DELETE WHILE IT WAS IN THE AST QUEUE ; (AF.MDE SET), DEALLOCATE THE BLOCK NOW. OTHERWISE CLEAR THE FLAG THAT ; INDICATES THE BLOCK IS IN THE AST QUEUE (AF.QUE). ; ; IF THE ACB IS FOR UNSOLICITED INPUT AST'S AND THE ACB IS NOT LOCKED (AF.LCK ; SET DUE TO TF.NOT CONSIDERATIONS), ATTEMPT TO GET ANOTHER CHARACTER FROM ; THE TYPEAHEAD BUFFER, WHICH WILL REQUEUE THE AST BLOCK. ; ; INPUTS: ; R0 => LINK WORD IN AST BLOCK ; ; OUTPUTS: NONE. ; ; REGISTERS MODIFIED: R1,R3,R5 ;- ; DQACB:: CALL MAPD ;MAP DRIVER DATA AREA MOVB A.PRM+5(R0),R1 ;GET THE ACB FLAGS ASSUME AF.MDE,200 BPL 3$ ;IF PL, NOT MARKED FOR DELETE MOV R0,-(SP) ;SAVE R0 JMP DEACB1 ;GO TO DEALLOCATE 3$: BICB #AF.QUE,A.PRM+5(R0) ;CLEAR FLAG SAYING WE ARE QUEUED .IF DF T$$OOB BIT #AF.OOB,R1 ;IS THIS AN OOB AST? BEQ 5$ ;BR IF NO TSTB A.PRM+24(R0) ;ANYTHING IN THE OOB TYPE AHEAD BUFFER BEQ 10$ ;IF NOT, WE'RE DONE MOV #FR.OOB,R3 ;STILL MORE CHARACTERS WAITING MTPS #TTPRI ;DISABLE INTERUPTS WHILE CHANGING FORK LIST CALL FORK ;;;SO SET UP FORK REQUEST MTPS #0 ;RE-ENABLE INTERPUTS BR 7$ 5$: .ENDC ;T$$OOB BIT #TF.AST,R1 ;IS THIS ACB FOR AN IO.ATA? BEQ 10$ ;IF EQ, NO...NOTHING ELSE TO DO BIT #AF.LCK,R1 ;IS THE ACB LOCKED? BNE 10$ ;IF NE, YES...DON'T CHECK MORE UNSOL. INPUT MOV A.PRM+2(R0),R5 ;GET POINTER TO U.TSTA 7$: .IF DF M$$PRO CLR R3 ;IF A SWITCH TO ANOTHER CPU TAKES PLACE, ;NO SPECIAL FORK PROCESSING ROUTINE IS ;REQUIRED - JUST GET ANOTHER CHARACTER ;FROM THE TYPE-AHEAD BUFFER CALL SWCPU ;SWITCH TO CORRECT CPU ; ; IF WE FALL THRU HERE, WE ARE ALREADY ON THE CORRECT CPU ; .ENDC ;M$$PRO CALL SETDSI ;DISABLE INPUT PROCESSING 10$: RETURN ;SIMULATE RETURN FROM A FORK PROCESSING ;ROUTINE IN ORDER TO GET ANOTHER CHARACTER ;FROM THE TYPE-AHEAD BUFFER .ENDC ;T$$CCA!T$$SCA!T$$MHU!T$$ICS!T$$OOB ; ; ;+ ; DELTB0 - DRIVER ENTRY POINT TO DEALLOCATE INTERMEDIATE BUFFERS ; FOR INPUT REQUEST. CALLED FROM $FINBF. ; ; INPUT: ; R0 POINTER TO FIRST INPUT BUFFER ;- ; ; DELTB0::CALL MAPD ;MAP DATA AREA .IF DF T$$ACD BIT #1,R0 ;DO BUFFER TRANSFER NOW? BEQ 10$ ;N - JUMP MOV R0,-(SP) ;Y - SAVE BUFFER ADDRESS CALL UBTRA ;CALL ROUTINE TO PERFORM THE TRANSFER MOV (SP)+,R0 ;RESTORE BUFFER POINTER DEC R0 ;MAKE EVEN .ENDC ;T$$ACD 10$: MOV R0,R2 ;GET FIRST BUFFER CALLR DELTB1 ;"FALL THRU" TO DELTB1 ; ; .SBTTL DELTB - DEALLOCATE A LINKED LIST OF TERMINAL BUFFERS ; ;+ ; DELTB - DEALLOCATE A LIST OF TERMINAL BUFFERS. ; ; INPUT: ; R2 ADDRESS OF FIRST BUFFER IN LIST, OR 0 ; CC-Z 0 IF R2 POINTS TO A BUFFER ; ; OUTPUT: ; BUFFER POINTED TO BY R2 AND ALL FOLLOWING BUFFERS DEALLOCATED. ; ; REGISTERS ALTERED: R0,R2 ;- ; ; .PSECT MAP6 DELTB1:: MOV @R2,-(SP) ;SAVE LINK TO NEXT CALL DETB ;DEALLOCATE THIS BUFFER MOV (SP)+,R2 ;GET NEXT BUFFER DELTB:: BNE DELTB1 ;THERE IS ONE - LOOP RETURN .PAGE .SBTTL . IRESET - RESET INPUT STATE PROCESSING FLAGS ; AND IRESEL (SAME AS IRESET BUT FIRST CALLS LOCKI) ; ;+ ; **-IRESET - RESET INPUT STATE FLAGS ; ; THIS ROUTINE RESETS THE FLAGS IN U.TSTA THAT AFFECT THE INPUT PRE-INPUT ; AND INPUT PROCESSES OF THE TERMINAL DRIVER. ALL FLAGS ARE FIRST CLEARED ; AND NEW SETTINGS ARE DERIVED FOR CERTAIN ONES FROM THE CURRENT STATE OF ; THE TERMINAL CHARACTERISTICS (U.TSTA+4). NOTE THAT THIS ROUTINE MAY BE ; CALLED FROM EITHER INTERRUPT STATE WHEN A TERMINATOR IS SEEN OR FROM FORK ; LEVEL WHEN COMPLETING AN INPUT REQUEST. ; ; INPUTS: ; R5 => U.TSTA OF THE TERMINAL UCB ; ; OUTPUTS: ; U.TSTA FLAGS SET ACCORDING TO CHARACTERISTICS IN U.TSTA+4 ; ; REGISTERS MODIFIED: NONE. ;- ; IRESEL:: CALL LOCKI ;LOCK OUT INTERUPTS IRESET:: BIC #S1.TNE!S1.RST!S1.PTH!S1.RNE!S1.TSY!S1.RES!S1.RNF!S1.RSP,(R5) ;;CLEAR UNWANTED FLAGS MOV 4(R5),-(SP) ;;GET CURRENT CHARACTERISTICS BIC #^C,(SP) ;;CLEAR EXTRANEOUS FLAGS ASSUME S3.RAL,S1.PTH ASSUME S3.NEC,S1.RNE ASSUME S3.TSY,S1.TSY BIT #S3.RAL,(SP) ;;IS TERMINAL IN READ-PASS-ALL MODE? BEQ 10$ ;;IF EQ, NO...SKIP BIC #S1.TSY,(SP) ;;READ-PASS-ALL FORCES NO TTSYNC (S1.PTH IS SET) 10$: BIT #S3.PTH,4(R5) ;;IS TERMINAL IN PASSTHRU MODE? BEQ 20$ ;;IF EQ, NO...SKIP BIS #S1.PTH,(SP) ;;SET PASSTHRU MODE IN THE FLAGS 20$: BIS (SP)+,(R5) ;;UPDATE THE INPUT STATE FLAGS RETURN ;;ALL DONE .PAGE .SBTTL . LOCKI/LOCKR - LOCK OUT INTERRUPTS AND RETURN ; ;+ ; LOCKI - LOCK OUT INTERRUPTS. ; THIS IS A COROUTINE THAT WORKS AS FOLLOWS: ; 1. RAISE PRIORITY TO LOCK OUT INTERRUPTS ; 2. CALL CALLER (OR CALL ROUTINE WHOSE ADDRESS ; IS ON TOP OF STACK) ; 3. DROP PRIORITY ; 4. RETURN ;- ; LOCKI:: MTPS #TTPRI ;LOCK OUT INTERRUPTS CALL @(SP)+ ;;;CALL COROUTINE LOCKR:: MTPS #0 ;;;ALLOW INTERRUPTS RETURN ;RETURN ; ERRORS IN GET/SET SPEED, PARITY OPTIONS OR FLOW CONTROL ; YJLPAR:: ;DJ11, DL11 DON'T HAVE SETTABLE YLLPAR:: ;LINE PARAMETERS YCLPAR:: ;NEITHER DOES THE PRO VIDEO INTERFACE TST R1 ;WAS THIS A NOTIFICATION OF FLOW CONTROL ;CHANGE? BEQ 10$ ;IF EQ NO - GO REPORT THE ERROR RETURN ;Else just return. The port doesn't need ;to be notified. 10$: .IF DF D$$H11!D$$Z11!D$$V11 .IF DF T$$OVL TST (SP)+ ;POP RETURN ADDRESS IN MPROT MOV (SP)+,KINAR5 ;RESTORE MAPPING CMP (SP)+,(SP)+ ;POP RETURN ADDRESSES OF THIS AND THAT .IFF ;T$$OVL TST (SP)+ ;POP RETURN ADDRESS .ENDC ;T$$OVL MOV (SP)+,R3 ;RESTORE R3 TST (SP)+ ;POP RETURN ADDRESS MOV (SP)+,R1 ;RESTORE BUFFER POINTER DEC R1 ;AND BACK IT UP CMP (SP)+,(SP)+ ;RETURNS FROM SPDPRM AND MCXSP .ENDC ;D$$H11!D$$Z11!D$$V11 CALLR ERCNSC ;CONTROLLER SPEED IS NOT SETTABLE .PAGE .IF DF T$$CCA!T$$SCA!T$$MHU!T$$ICS!T$$OOB .SBTTL . DEACB/DEACB1 - DEALLOCATE AN AST CONTROL BLOCK ; ;+ ; **-DEACB - DEALLOCATE AN AST CONTROL BLOCK ; ; THIS ROUTINE IS CALLED WHEN AN AST CONTROL BLOCK NEEDS TO BE ; DEALLOCATED OR A TSA EVENT PACKET NEEDS TO BE PASSED TO IT'S OWNER ; FOR DEALLOCATION PROCESSING. AN ACB IS DISTINGUISHED FROM A TEP BY ; OFFSETS A.CBL/E.VSIZ. AN ACB HAS A ZERO IN THIS WORD; A TEP IS NON-ZERO. ; IF THE PACKET IS A TEP, IT IS MARKED FOR DELETE AND QUEUED TO THE OWNER. ; IF IT IS AN ACB, IT IS MARKED FOR DELETE AND A CHECK IS MADE TO SEE IF ; IT IS IN A TASK'S AST QUEUE (AF.QUE SET). IF SO, IT WILL BE DEALLOCATED ; WHEN IT IS DEQUEUED LATER ON (WITH A CALL TO DQACB). OTHERWISE THE SIZE ; OF THE ACB IS OBTAINED AND IT IS DEALLOCATED. ; ; INPUTS: ; FOR ENTRY AT DEACB: ; (R4) => UCBX LOCATION HOLDING ADDRESS OF ACB/TEP TO DEALLOCATE ; R5 => UCB FOR THE TERMINAL IF PACKET IS A TEP ; ; FOR ENTRY AT DEACB1: ; R0 => THREAD WORD OF THE ACB (STRUCTURE HAS NEGATIVE OFFSETS) OR TEP ; ; OUTPUTS: NONE. ; ; REGISTERS MODIFIED: R2 MAY BE DESTROYED BY THE OWNER ROUTINE ;- ; .ENABL LSB DEACB:: MOV R0,-(SP) ;SAVE R0 MOV (R4),R0 ;GET THE ACB/TEP BEQ 30$ ;IF EQ, NONE...RETURN CLR (R4) ;INDICATE IT HAS BEEN DELETED .IF DF T$$TSA ASSUME A.CBL,E.VSIZ TST A.CBL(R0) ;IS THIS AN AST CONTROL BLOCK? BEQ 10$ ;IF EQ, YES...DEALLOCATE IT MOV R3,-(SP) ;SAVE REGISTER MOV R1,-(SP) ;SAVE REGISTER MOV R0,R3 ;COPY TEP ADDRESS FOR QUEUEING BISB #EF.MDE,E.VFLG(R3) ;MARK TEP FOR DELETE CALL QUETEP ;PASS TEP TO NETWORK FOR DEALLOCATION BR 20$ ;SKIP TO FINISH UP 10$: .ENDC ;T$$TSA BISB #AF.MDE,A.PRM+5(R0) ;MARK THE ACB FOR DELETE BITB #AF.QUE,A.PRM+5(R0) ;IS ACB CURRENTLY IN AST QUEUE? BNE 30$ ;IF NE, YES...WAIT FOR IT TO BE DEQUEUED ; ; HERE TO ACTUALLY DEALLOCATE AN ACB. ; DEACB1:: MOV R3,-(SP) ;SAVE I/O PACKET ADDRESS MOV R1,-(SP) ;SAVE REGISTER MOVB A.PRM+4(R0),R1 ;GET LENGTH OF THE ACB CMP -(R0),-(R0) ;BACK UP TO START OF THE ACB CALL $DEACB ;DEALLOCATE THE BLOCK 20$: MOV (SP)+,R1 ;RESTORE REGISTER MOV (SP)+,R3 ;RESTORE PACKET ADDRESS 30$: MOV (SP)+,R0 ;RESTORE R0 RETURN ;ALL DONE .DSABL LSB .ENDC ;T$$CCA!T$$SCA!T$$MHU!T$$ICS!T$$OOB ;+ ; **-MPROT- MAP AND CALL SPECIFIED ROUTINE WITHIN THE ROOT (MAIN ; APR5 MAPPING) OF THE TERMINAL DRIVER, RESTORE PREVIOUS MAPPING ; AND RETURN TO CALLER ; ; INPUTS: ; ; 2(SP) = ADDRESS OF APR5 ROUTINE TO BE CALLED ; (SP) = ADDRESS OF TO WHICH TO RETURN WHEN DONE ; ; OUTPUTS: ; ; NONE. ; ; ALL REGISTERS ARE PRESERVED. ;- .IF DF T$$OVL ;IF SYSTEM CONTAINS MEMORY-OVERLAID TTDRV MPROT:: MOV 2(SP),-(SP) ;DUPLICATE ADDRESS TO CALL MOV 2(SP),4(SP) ;PUT RETURN ADDRESS WHERE IT SHOULD BE MOV KINAR5,2(SP) ;SAVE CURRENT MAPPING MOV ROTMAP,KINAR5 ;MAP MAIN ROOT OF TTDRV CALL @(SP)+ ;AND CALL ROUTINE MOV (SP)+,KINAR5 ;RESTORE MAPPING RETURN ;RETURN TO CALLER ;+ ; **-MPEXT- MAP AND CALL SPECIFIED ROUTINE WITHIN THE OVERLAY (TTEXT), ; RESTORE PREVIOUS MAPPING AND RETURN TO CALLER ; ; INPUTS: ; ; R1 = ADDRESS OF APR5 ROUTINE TO BE CALLED ; ; OUTPUTS: ; ; NONE. ; ; ALL REGISTERS ARE PRESERVED. ;- MPEXT:: MOV KINAR5,-(SP) ;SAVE CURRENT MAPPING MOV EXTMAP,KINAR5 ;MAP MAIN ROOT OF TTDRV CALL (R1) ;AND CALL ROUTINE MOV (SP)+,KINAR5 ;RESTORE MAPPING RETURN ;RETURN TO CALLER ;+ ; **-TRANSFERS TO AND FROM THE ROOT ; ; TRANSFER FROM TTINI TO QPEIO QPETRA:: MOV EXTMAP,KINAR5 ;MAP THE EXTENSION CALLR QPEIO1 ;JMP TO QPEIO1 ; ; TRANSFER FROM QPEIO1 TO QPWLB QPWTRA:: MOV ROTMAP,KINAR5 ;MAP THE ROOT CALLR QPWLB ;JMP TO QPWLB ; ; TRANSFER FROM TTATT TO QUEUE QUETRA:: MOV ROTMAP,KINAR5 ;MAP THE ROOT CALLR QUEUE ;JMP TO QUEUE .ENDC ;T$$OVL ; ; .SBTTL ALTB - ALLOCATE A TERMINAL BUFFER ; ;+ ; ALTB - ALLOCATE TERMINAL BUFFER. ; ; INPUT: ; NONE ; ; OUTPUT: ; IF SUCCESS: ; CC-C 0 ; R2 POINTER TO BUFFER WITH LENGTH T$$BFL BYTES. ; FIRST WORD CLEARED. ; ; IF FAILURE: ; CC-C 1 ; ; REGISTERS ALTERED: R0,R2 ;- ; ; ALTB:: MOV FREEB,R2 ;GET FIRST FREE BUFFER BEQ 20$ ;NONE - JUMP MOV @R2,FREEB ;POINT TO NEXT FREE BUFFER 10$: CLR @R2 ;CLEAR LINK WORD RETURN 20$: MOV R1,-(SP) ;SAVE R1 MOV #T$$BFL,R1 ;SET DESIRED LENGTH CALL $ALOCB ;ALLOCATE IN SYSTEM POOL MOV (SP)+,R1 ;RESTORE R1 MOV R0,R2 ;GET BUFFER IN R2 BCC 10$ ;OK - JUMP RETURN ;ELSE RETURN WITH CARRY SET .PAGE .IFT ;NDF T$$SPL .SBTTL CKTAB - CHECK FOR TYPE-AHEAD BUFFER ALLOCATION OR DEALLOCATION ; ;+ ; CKTAB - CHECK WHETHER TYPE-AHEAD BUFFER SHOULD BE ALLOCATED ; OR DEALLOCATED. ; ; INPUT: ; R5 POINTER TO U.TSTA ; S3.TAB 0 DEALLOCATE TYPE-AHEAD BUFFER IF ONE IS ALLOCATED ; (LOSING ALL CHARACTERS STORED IN IT) ; 1 ALLOCATE TYPE-AHEAD BUFFER IF NONE IS ALLOCATED ; (LOSING SINGLE CHARACTER IF THERE IS ONE) ; ; REGISTERS ALTERED: R0,R2 ;- ; ; CKTAB:: CALL LOCKI ;LOCK OUT INTERRUPTS MOV U.TTAB-U.TSTA(R5),R2 ;;;GET TYPE-AHEAD BUFFER BEQ 10$ ;;;NONE - JUMP BIT #1,R2 ;;;SINGLE-CHARACTER BUFFER? BNE 10$ ;;;Y - JUMP ; ; TYPE-AHEAD BUFFER EXISTS ; BIT #S3.TAB,4(R5) ;;;DEALLOCATE BUFFER? BNE 20$ ;;;N - JUMP CALL DETB ;;;Y - DO IT CLR U.TTAB-U.TSTA(R5) ;;;SHOW NO BUFFER ANY MORE BR 20$ ;;; ; ; TYPE-AHEAD BUFFER DOES NOT EXIST ; 10$: BIT #S3.TAB,4(R5) ;;;ALLOCATE BUFFER? BEQ 20$ ;;;N - JUMP CALL ALTB ;;;Y - DO IT BCS 20$ ;;;FAILED - JUMP MOV R2,U.TTAB-U.TSTA(R5) ;;;SAVE POINTER TO BUFFER CLR (R2)+ ;;;INITIALIZE HEADER MOV #*400,@R2 ;;; ; ; ALL DONE ; 20$: RETURN ;;;RETURN VIA COROUTINE THAT DROPS ;;;PRIORITY .ENDC ;NDF T$$SPL .PAGE .SBTTL EXPCHR - EXPAND AN OUTPUT CHARACTER ; ;+ ; EXPCHR - THIS MODULE CONTAINS THE ROUTINES TO EXPAND CHARACTERS ; INTO STRINGS ON OUTPUT AS REQUIRED. ; ; THESE ROUTINES ARE CALLED BOTH AT SYSTEM STATE (WHEN SETTING ; UP A WRITE REQUEST) AND FROM THE INPUT INTERRUPT SERVICE ; ROUTINE (TO GENERATE AN ECHO). THEREFORE, THE MODULE MUST ; BE REENTRANT. ;- ; ; ; EXPAND A CHARACTER ; ;+ ; EXPCHR - EXPAND A CHARACTER. ; ; INPUT: ; R2 CHARACTER ; R5 POINTER TO U.TSTA ; U.TCHP CURRENT HORIZONTAL POSITION ; U.TCVP CURRENT VERTICAL POSITION ; S2.FLF 1 IF LINE FEED MUST BE OUTPUT BEFORE NEXT ECHO ; S2.ELF 1 IF A LINE-FEED SHOULD BE DISCARDED ; ; OUTPUT: ; IF THE EXPANSION IS A SINGLE CHARACTER: ; CC-Z 1 ; R2 UNCHANGED ; IF THE EXPANSION IS A STRING: ; CC-Z 0 ; R2 LENGTH OF EXPANDED STRING ; R3 POINTER TO EXPANDED STRING ; IF CHARACTER SHOULD BE KEPT AND PRESENTED AGAIN ON ; NEXT CALL TO EXPCHR (ONLY RELEVANT IF CC-Z = 0): ; CC-C 1 ; IF CHARACTER SHOULD NOT BE PRESENTED AGAIN: ; CC-C 0 ; IF THE CHARACTER IS A LINE-FEED AND SHOULD BE DISCARDED ; CC-V 1 ; R2 UNCHANGED ; ALWAYS: ; U.TCHP UPDATED TO POSITION AFTER STRING HAS BEEN OUTPUT ; U.TCVP UPDATED TO POSITION AFTER STRING HAS BEEN OUTPUT ; S2.FLF 1 IF A CARRIAGE RETURN WAS RETURNED ; 0 ELSE ; S2.ELF 0 IF THE V-BIT GETS SET OR IF THE CHARACTER ; WAS ANY ONE EXCEPT CR ,ESC,BSP OR FF ; ; REGISTERS ALTERED: R2,R3 ; ; THE PROPER WAY TO USE EXPCHR IS TO FIRST SAVE THE CHARACTER, ; THEN CALL EXPCHR, THEN OUTPUT THE STRING DESCRIBED BY R2,R3. ; IF CC-C WAS SET ON RETURN FROM EXPCHR, ON THE NEXT CALL TO ; EXPCHR THE SAME CHARACTER MUST BE PRESENTED IN R2, OTHERWISE ; THE NEXT CHARACTER. ;- ; ; .ENABL LSB ; EXCR1:: MOVB #CH.CR,R2 ;EXPAND A CARRIAGE RETURN BR EXPCHR ; ; EXPC3:: BIT #S2.WAL,2(R5) ;WRITE PASS ALL? BEQ EXPCHR ;N - JUMP SEZ ;Y - EXIT WITH CC-Z = 1 RETURN ; ; EXPCHR::CLR -(SP) ;INITIALIZE FLAG TO 0 TO EXIT WITH: ; CC-C = 0 (DON'T KEEP CHAR) ; CC-Z = 1 (OUTPUT CHAR) MOVB U.TCHP-U.TSTA(R5),@SP ;GET CURRENT HOR. POSITION TST (R5)+ ;POINT TO U.TSTA+2 MOVB @R5,R3 ;GET CONTEXT FOR WRAP-AROUND BIC #^C,R3 ;CLEAR IRRELEVANT BITS ASSUME S2.WRA,6 JMP @OSDSP(R3) ;DISPATCH ; ; ; DEFAULT CASE - NO SPECIAL THINGS IN PROGRESS ; EXPC0:: BIT #S2.FLF,@R5 ;FORCE A LINE FEED? BNE 40$ ;Y - JUMP CMPB R2,#CH.ESC ;ESCAPE? BEQ EXESC ;Y - JUMP CMPB R2,#CH.CR ;CARRIAGE RETURN? BHI EXDEF ;N - HIGHER, CAN'T BE IN RECOGNITION ;TABLE - JUMP TO DEFAULT ROUTINE BEQ EXCRJ ;CARRIAGE RETURN - JUMP MOV #EXCRT,R3 ;POINT TO START OF CHAR. RECOGNITION TABLE ;FALL THRU TO "CHRDSP" ; ; ; DISPATCH ACCORDING TO CHARACTER ; ;+ ; CHRDSP - DISPATCH ACCORDING TO CHARACTER. ; ; INPUT: ; R2 CHARACTER ; R3 START OF CHARACTER RECOGNITION TABLE ; ; OUTPUT: ; JUMPS TO CHARACTER PROCESSING ROUTINE WITH R2 UNCHANGED. ;- ; ; CHRDSP::TSTB (R3)+ ;END OF TABLE? BEQ 30$ ;Y - JUMP CMPB R2,-1(R3) ;MATCH? BNE CHRDSP ;N - LOOP 30$: SUB #CHRT+1,R3 ;GET OFFSET FROM CHRT ASL R3 ;MAKE WORD INDEX JMP @CHRD(R3) ;JUMP TO ROUTINE .PAGE ; ; ; EXPAND ESCAPE ; ASSUME U.TCVP, EXESC: CLR U.TCHP-(R5) ;CLEAR HORIZONTAL AND VERTICAL POSITION JMP 180$ ;OUTPUT THE ESCAPE AS IS ; ; FORCE LINE FEED ; 40$: CMPB R2,#CH.LF ;IS THE CHARACTER A LINE FEED? BEQ EXLF ;Y - JUMP BR 50$ ;N - NEED CHARACTER AGAIN ; ; DO THE LINE FEED FOR WRAP-AROUND ; EXPC1:: ADD #S2.WRB,@R5 ;NEXT TIME GO TO EXPC2 TO DO THE ;CHARACTER ITSELF BR 50$ ; ; ; ; EXPAND FORM FEED AND VERTICAL TAB IF NECESSARY ; EXVT:: EXFF:: BIT #S4.HFF,4(R5) ;SIMULATE FORM FEEDS? BNE 110$ ;N - JUMP ; 50$: COMB 1(SP) ;WE NEED CHARACTER AGAIN, EXIT WITH: ; CC-C = 1 (KEEP CHAR) ; CC-Z = 0 (OUTPUT STRING) ; ; ; EXPAND LINE FEED ; EXLF:: BIC #S2.FLF,@R5 ;CLEAR FORCE-LF FLAG BIT #S2.ELF,@R5 ;SHOULD WE EAT THE LF? BEQ 55$ ;BR IF NO BIC #S2.ELF,@R5 ;NEXT SHOULD NOT BE DISCARDED CMP -(R5),(SP)+ ;POINT TO U.TSTA AND POP THE FLAG OFF THE STACK SEV ;SET STATUS BIT RETURN 55$: MOV #ASLF,R3 ;POINT TO LF BIS #400,@SP ;EXIT WITH: ; CC-C = ? (NO CHANGE) ; CC-Z = 0 (OUTPUT STRING) INCB U.TCVP-(R5) ;UPDATE CURRENT VERTICAL POS. CALL 190$ ;RESET POSITION IF CROSSED A PAGE LIMIT BHIS 60$ ;BRANCH IF CROSSED A PAGE LIMIT CMPB R2,#CH.FF ;FORMFEED? BEQ 90$ ;Y - JUMP BR 70$ ;N - JUMP 60$: CMPB R2,#CH.FF ;IS THE CHARACTER A FF? BEQ 80$ ;Y - JUMP 70$: CMPB R2,#CH.VT ;IS THIS A VT? BNE 120$ ;N - JUMP BITB #7,U.TCVP-(R5) ;ARE WE AT A VERT. TAB STOP? BNE 90$ ;N - JUMP 80$: BIC #140000,@SP ;Y - DON'T WANT CHAR AGAIN EXIT WITH ; CC-C = 0 (DON'T KEEP) ; CC-Z = 0 (OUTPUT STRING) ; CC-N = 0 (INSURE CC-V = 0 AFTER ROL) 90$: BIT #U2.CRT,U.CW2-(R5) ;CRT? BEQ 120$ ;N - JUMP MOV #4,R2 ;Y - ECHO 4 LF'S IN PLACE OF FF OR VT SUB R2,R3 ;POINT TO FIRST OF 4 LINE FEEDS BIT #S4.VFL,4(R5) ;VERTICAL FILL REQUIRED? BEQ 100$ ;N - JUMP MOV #<1+NLFF>*4,R2 ;Y - ECHO 4 LF'S PLUS FILLER SUB R2,R3 ;POINT TO START OF OUTPUT STRING 100$: MOVB U.TCVP-(R5),-(SP) ;UPDATE VERTICAL POSITION ADD #3,@SP ;(ADD 3 SINCE 1 LF WAS ALREADY COUNTED) MOVB (SP)+,U.TCVP-(R5) ;MUCH PAIN FOR ADD TO ODD ADRS CALL 190$ ;CORRECT POSITION IF CROSSED A PAGE LIMIT BIC #140000,@SP ;DON'T KEEP CHAR 110$: BR 180$ ;FILL CHARACTERS ALREADY ACCOUNTED FOR 120$: MOV #1,R2 ;ASSUME NO FILLERS REQUIRED BIT #S4.VFL,4(R5) ;VERTICAL FILL REQUIRED? BEQ 180$ ;N - JUMP ADD #NLFF,R2 ;Y - ADD NUMBER OF FILL CHARACTERS BR 180$ ;DON'T CHANGE HOR. POS. OR BYTE COUNT ; ; ; EXPAND BACKSPACE ; EXBSP:: TSTB @SP ;AT LEFT MARGIN? BEQ 180$ ;Y - EXIT (DON'T CHANGE HOR. POS.) DECB @SP ;N - BACKSPACE BR 170$ ;EXIT ; EXCRJ: BR EXCR ;BRANCH AID ; ; ; CR AND LF FOR WRAP-AROUND HAVE BEEN DONE. DO THE CHARACTER ITSELF. ; NOTE - THE CHARACTER MUST BE EITHER A HORIZONTAL TAB OR A ; "NORMAL" CHARACTER, SINCE ONLY THOSE CAUSE WRAP-AROUND. ; EXPC2:: BIC #S2.WRA,@R5 ;CLEAR WRAP-AROUND CONTEXT CMPB R2,#CH.HT ;HORIZONTAL TAB? BNE EXDEF ;N - JUMP ; ; ; EXPAND HORIZONTAL TAB ; EXHT:: MOV @SP,R3 ;GET CURRENT HOR.POS. BIC #S2.ELF,@R5 ;CLEAR DISCARD LF BIT BIS #7,@SP ;POINT JUST BEFORE NEXT TAB STOP BIT #S4.HHT,4(R5) ;HARDWARE HOR. TAB PRESENT? BNE 130$ ;Y - JUMP MOV R3,R2 ;GET CURRENT HOR. POS. SUB @SP,R2 ;GET NUMBER OF SPACES NECESSARY ;NEGATED AND OFF BY 1 NEG R2 ;MAKE POSITIVE INC R2 ;ADJUST MOV #ASHT,R3 ;POINT TO HTAB BIS #400,@SP ;OUTPUT IS A STRING, EXIT WITH: ; CC-C 0 (DON'T KEEP CHAR.) ; CC-Z 0 (OUTPUT STRING) BR 130$ ;CHECK FOR WRAP-AROUND ; ; ; EXPAND NORMAL CHARACTER ; EXDEF:: BIC #S2.ELF,@R5 ;CLEAR DISCARD LF BIT BIT #140,R2 ;NON-SPACING CHARACTER? BEQ 180$ ;Y - EXIT BIT #U3.UPC,U.CW3-(R5) ;TERMINAL SUPPORT LOWERCASE? BEQ 130$ ;Y - JUMP ;NOTE THAT LOWER TO UPPER CASE CONVERSION IS NOT ;PERFORMED HERE FOR THE GR CHARACTER SET SINCE A ;TERMINAL CAPABLE OF DISPLAYING 8-BIT CHARACTERS ;WILL NEVER GET PAST THE CHECK ABOVE CMPB R2,#141 ;CHARACTER NEED CONVERTING? BLO 130$ ;N - JUMP CMPB R2,#172 ;SECOND CHECK BHI 130$ ;N - JUMP BICB #40,R2 ;CONVERT LOWERCASE TO UPPERCASE 130$: CMPB @SP,U.CW4-(R5) ;AT RIGHT MARGIN? BLO 160$ ;N - JUMP BIT #S3.ACR,2(R5) ;AUTO CR-LF WANTED? BEQ 160$ ;N - JUMP COMB 1(SP) ;NEED CHARACTER AGAIN, EXIT WITH: ; CC-C = 1 (KEEP CHAR) ; CC-Z = 0 (OUTPUT STRING) ADD #S2.WRB,@R5 ;SET STATE VARIABLE TO COME BACK AT EXPC1 ;TO DO THE LINE FEED ;FIRST DO A CARRIAGE RETURN ; ; ; EXPAND A CARRIAGE RETURN ; EXCR:: BIS #400,@SP ;EXIT WITH: ; CC-C = ? (NO CHANGE) ; CC-Z = 0 (OUTPUT STRING) ASSUME S4.HFL,7 MOVB 4(R5),R2 ;GET HOR. FILL REQUIREMENT BIC #^C,R2 ;CLEAR OTHER BITS CMP R2,#7 ;FILL FOR LA30S? BNE 150$ ;N - JUMP MOVB @SP,R2 ;Y - GET CURRENT HOR.POS. .IF DF R$$EIS ASH #-3,R2 ;DIVIDE BY 8 .IFF ASR R2 ;DIVIDE BY 8 ASR R2 ASR R2 .ENDC CMP R2,#9. ;WITHIN TABLE RANGE? BLOS 140$ ;Y - JUMP MOV #9.,R2 ;N - SET TO HIGHEST VALUE 140$: MOVB HORFT(R2),R2 ;GET FILL COUNT FROM TABLE 150$: MOV #ASCR,R3 ;POINT TO CR MOVB #-1,@SP ;INITIALIZE CURRENT HOR. POS. ;BOTH BYTE COUNT AND HOR. POS. ;WILL BE INCREMENTED ON EXIT BIS #S2.FLF,@R5 ;FORCE A LINEFEED ON NEXT ECHO INC R2 ;INCR. BYTE COUNT ; ; 160$: INCB @SP ;UPDATE HOR. POS. 170$: MOVB @SP,U.TCHP-(R5) ;STORE UPDATED HOR. POS. 180$: TST -(R5) ;POINT TO U.TSTA CLRB @SP ;CLEAR LOW BYTE ROL (SP)+ ;GET FLAGS TO GENERATE PROPER ;CONDITION CODES RETURN ; ; 190$: CMPB U.TCVP-(R5),U.TLPP-(R5) ;CROSSED A PAGE LIMIT? BLO 200$ ;N - RETURN CLRB U.TCVP-(R5) ;Y - RESET TO 0 BIT #U2.CRT,U.CW2-(R5) ;CRT? BEQ 200$ ;N - RETURN MOVB U.TLPP-(R5),U.TCVP-(R5) ;Y - CRT'S SCROLL, NOT ROLL DECB U.TCVP-(R5) ;CURSOR STAYS ON BOTTOM LINE 200$: RETURN ; .DSABL LSB ; ; .IF DF T$$CUP .PAGE .SBTTL CPOS - SUBROUTINE TO EXPAND CURSOR POSITIONING COMMAND ; ;+ ; CPOS - EXPAND CURSOR COORDINATES TO CURSOR POSITIONING COMMAND ; SUITABLE FOR THE TERMINAL TYPE. ; ; INPUT: ; R2 LOW BYTE: COLUMN NUMBER (STARTING AT 1) ; HIGH BYTE: LINE NUMBER (STARTING AT 1) ; R5 POINTER TO U.TSTA ; ; OUTPUT: ; R2 LENGTH OF CURSOR POSITIONING COMMAND ; R3 POINTER TO CURSOR POSITIONING COMMAND ; CC-C 0 ; CC-Z 0 ; ; REGISTERS ALTERED: R2,R3 ;- ; ; CPOS:: ; ; USE U.TTYP TO DETERMINE HOW TO EXPAND COMMAND. ; MOVB U.TTYP-U.TSTA(R5),R3 ;GET TERMINAL TYPE BEQ CPOS0 ;NOT RECOGNIZED - JUMP CMP R3,#TTPHI ;RECOGNIZED? BHI CPOS0 ;N - JUMP MOVB TTYP1-1(R3),R3 ;Y - GET CURSOR POS. TYPE IN BITS 6-7 .IF DF R$$EIS ASH #-5,R3 ;GET IT IN BITS 1-2 .IFF ASL R3 ;SHIFT INTO BITS 9-10 ASL R3 ; ASL R3 ; SWAB R3 ;GET IT IN BITS 1-2 .ENDC BIC #^C6,R3 ;CLEAR ALL OTHER BITS BEQ CPOS0 ;NO CURSOR POSITIONING IMPLEMENTED - JUMP MOV R2,-(SP) ;SAVE ORIGINAL COORDINATES BIC #100000,R2 ;CLEAR SCREEN CLEAR BIT MOV R2,U.TCHP-U.TSTA(R5) ;SET NEW CURSOR POSITION JMP @CPOST-2(R3) ;JUMP VIA JUMP TABLE .ENABL LSB ; ; TYPE 0 - CURSOR POSITIONING NOT IMPLEMENTED ; CPOS0: CLR R2 ;EXPAND INTO A SINGLE NULL RETURN ;RETURN WITH CC-C = 0, CC-Z = 1 ; ; TYPE 1 - VT05 ; CPOS1:: ADD #401*40,R2 ;BIAS BOTH COORDINATES BY 40 MOVB R2,CP1+20 ;STORE X COORD. SWAB R2 ;GET Y COORD. AND CLEAR CC-C MOVB R2,CP1+13 ;STORE Y COORD. MOV #7,R2 ;STRING LENGTH = 7 MOV #CP1+12,R3 ;POINTER TO STRING TST (SP)+ ;CLEAR SCREEN REQUESTED? CLZ ;(LEAVE CC-Z CLEAR) BPL 10$ ;N - RETURN SUB #12,R3 ;POINT TO CLEAR SCREEN ESCAPE SEQUENCE ADD #12,R2 ;ADD THAT TO CURSOR POSITION OUTPUT 10$: RETURN ;RETURN ; ; TYPE 2 - VT52 AND VT50H ; CPOS2:: SWAB R2 ;GET COLUMN IN HIGH BYTE, LINE IN LOW BYTE ADD #401*40,R2 ;BIAS BOTH COORDINATES BY 40 MOV #CP2+6,R3 ;POINT TO COMMAND STRING + 2 MOV R2,@R3 ;STORE COORDINATES TST -(R3) ;POINT TO START OF STRING AND CLEAR CC-C MOV #4,R2 ;LENGTH = 4 TST (SP)+ ;CLEAR SCREEN REQUESTED? CLZ ;(LEAVE CC-Z CLEAR) BPL 10$ ;N - RETURN SUB #4,R3 ;Y - POINT TO CLEAR SCREEN ESCAPE SEQUENCE BR 20$ ;FINISH IT OFF ; ; TYPE 3 - VT100 ; CPOS3:: MOV R0,-(SP) ;SAVE R0, R1 MOV R1,-(SP) ; MOV #CP3A,R3 ;POINT AT FINAL CHARACTER CALL 30$ ;EXPAND X-COORD. TO ASCII MOVB #';,-(R3) ;INSERT DELIMITER SWAB R2 ;GET Y-COORD. CALL 30$ ;EXPAND IT MOV (SP)+,R1 ;RESTORE R0, R1 MOV (SP)+,R0 ; MOVB #'[,-(R3) ;INSERT CONTROL SEQUENCE INTRODUCER MOVB #CH.ESC,-(R3) ; .. (BACKWARDS) MOV #CP3A+1,R2 ; SUB R3,R2 ;GET STRING LENGTH AND CLEAR CC-C AND CC-Z TST (SP)+ ;WAS CLEAR SCREEN REQUESTED? CLZ ;(LEAVE CC-Z CLEAR) BPL 10$ ;N - RETURN MOVB #'J,-(R3) ;INSERT... MOVB #'2,-(R3) ;...CLEAR SCREEN ESCAPE SEQUENCE... MOVB #'[,-(R3) ;...INTO OUTPUT STRING... MOVB #CH.ESC,-(R3) ;...BACKWARDS 20$: ADD #4,R2 ;ADD THAT TO CURSOR POSITION OUTPUT RETURN ;RETURN 30$: CLR R1 ; BISB R2,R1 ;GET NUMERIC VALUE INC R1 ;ADJUST TO BASE 1 .IF DF R$$EIS 40$: CLR R0 ;CLEAR HIGH ORDER DIVIDEND DIV #10.,R0 ;DIVIDE BY 10 .IFF ;R$$EIS 40$: MOV R1,R0 ;GET DIVIDEND MOV #10.,R1 ;GET DIVISOR CALL $DIV ;DIVIDE BY 10 .ENDC ;R$$EIS BIS #'0,R1 ;BIAS REMAINDER BY ASCII /0/ MOVB R1,-(R3) ;STORE IN STRING MOV R0,R1 ;GET QUOTIENT BNE 40$ ;NON-ZERO - DO IT AGAIN RETURN ;RETURN .ENDC ;T$$CUP .DSABL LSB .PAGE .SBTTL UBTRA - BUFFERED ACD TRANSFER ROUTINE ; ;+ ; UBTRA - TRANSFER BUFFERS FROM THE ACD TO A TASK AT $FINBF TIME ; ; INPUT: ; R0 ADDRESS OF BUFFER CONTAINING TRANSFER PARAMETERS ; ; OUTPUT: ; THE CHARACTERS DESCRIBED BY THE BUFFER PARAMETERS ARE TRANSFERRED ; FROM THE ACD TO THE TASK. THE ACD IS THEN CALLED BACK TO ; DEALLOCATE ITS BUFFER AND POSSIBLY TO REQUEST ANOTHER TRANSFER. ; ; REGISTERS ALTERED: ALL ;- ; ; .IF DF T$$ACD UBTRA:: ADD #3,R0 ;POINT PAST LINK WORD MOV (R0)+,R5 ;GET UCB ADDRESS MOV (R0)+,R3 ;GET I/O PACKET ADDRESS MOV I.PRM+2(R3),R4 ;GET TASK BUFFER DISPLACEMENT 10$: MOV R3,-(SP) ;SAVE R3 MOV (R0)+,R1 ;GET ACD BUFFER APR BIAS (A.SMAP) MOV (R0)+,R2 ;GET ACD BUFFER DISPLACEMENT (A.SBUF) SUB #20000,R2 ;CONVERT TO AN APR5 MAPPING MOV (R0)+,R3 ;GET TASK PCB ADDRESS MOV P.REL(R3),R3 ;GET TASK APR BIAS ADD (R0)+,R3 ;COMPUTE TASK BUFFER APR BIAS 20$: MOV (R0),R0 ;GET TRANSFER LENGTH (A.SLEN) CALL $BLXIO ;PERFORM THE TRANSFER MOV R3,R1 ;SAVE R3 IN CASE ACD CONTINUES TRANSFER MOV (SP)+,R3 ;RESTORE I/O PACKET ADDRESS BIC #UA.CAL,U.AFLG-U.TSTA(R5) ;SET DEFAULT PROCESSING MOV #A.CALL,R0 ;SET TRANSFER CALLBACK ENTRY POINT CALL $SWACD ;CALL ACD BIT #UA.CAL,U.AFLG-U.TSTA(R5) ;MORE TO GO? BEQ 30$ ;N - JUMP MOV R3,-(SP) ;Y - SAVE I/O PACKET ADDRESS MOV R1,R3 ;RESTORE TASK BUFFER APR BIAS MOV U.ACB-U.TSTA(R5),R0 ;GET ACB ADD #A.SMAP,R0 ;POINT TO ACD BUFFER PARAMETERS MOV (R0)+,R1 ;GET ACD BUFFER APR BIAS MOV (R0)+,R2 ;GET ACD BUFFER DISPLACEMENT SUB #20000,R2 ;CONVERT TO AN APR5 MAPPING BR 20$ ;DO THE TRANSFER 30$: RETURN .ENDC ;T$$ACD .END